package cn.springsoter.core.tool.config;

import java.util.Date;
import java.util.List;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.ResourceHttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;

import cn.springsoter.core.tool.serializer.JsonDateSerializer;

@Configuration
public class JacksonConfig implements WebMvcConfigurer {
	
	/**
	 * spring 内置有8种Message Converter：
	 * 
	 *  1.StringHttpMessageConverter
		它支持 text/plain 类型的消息，够将请求消息体中的内容转换为String类型，也可以返回的对象，转换为字符串写入到响应的消息体中。
		
		2.FormHttpMessageConverter
		它支持 application/x-www-formurlencoded 类型的消息，会将请求消息体中的内容转化为MultiValueMap<String, String>。
		
		3.ByteArrayHttpMessageConverter
		它默认支持所有媒体类型，会将请求的消息体读取到一个byte数组中。
		
		4.MarshallingHttpMessageConverter
		它支持 text/xml 和 application/xml 类型的消息，它利用 org.springframework.oxm 中的抽象类 Marshaller 和 Unmarshaller来实现对于XML消息的转换。
		
		5.MappingJackson2HttpMessageConverter
		它支持 application/json 类型的消息，利用 Jackson 的ObjectMapper 实现JSON的转换.
		
		6.MappingJackson2XmlHttpMessageConverter
		它支持 application/xml 类型的消息，利用 Jackson 实现 XML的转化
		
		7.SourceHttpMessageConverter
		它支持 application/xml 类型的消息，将XML转化为 javax.xml.transform.Source 中的DOMSource， SAXSource，与 StreamSource三种类型
		
		8.BufferedImageHttpMessageConverter
		它支持将请求中的内容转化为java.awt.image.BufferedImage
		
		另外Spring还提供了基于Gson的Message Converter: GsonHttpMessageConverter 实现JSON消息的转换
	 * 
	 */
	@Override
	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
		// 解决文件下载抛HttpMediaTypeNotAcceptableException异常: Could not find acceptable representation
		// ResourceHttpMessageConverter支持所有的MediaType
		converters.add(new ResourceHttpMessageConverter(true));
		
		// 解析text/plain类型的数据
		StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
	    stringConverter.setWriteAcceptCharset(false);
	    converters.add(stringConverter);
	}

	@Bean
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        SimpleModule simpleModule = new SimpleModule();
    	simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Date.class, new JsonDateSerializer());
        // 全局配置：解决返回json为null的问题，使用：MappingJackson2HttpMessageConverter
//        ApiNullValueJacksonHttpMessageConverter converter = new ApiNullValueJacksonHttpMessageConverter();
//        simpleModule.setSerializerModifier(converter.new MyBeanSerializerModifier());
        
        objectMapper.registerModule(simpleModule);
        // 允许key有单引号
    	objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
        // 全局配置：忽略null的字段
//        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return objectMapper;
    }
}
